<?php
require_once 'PHPUnit/Framework.php';
require_once "amicitia/conf/Conf.class.php";
require_once 'amicitia/arquitectura/Cargador.class.php';
def("amicitia/modelo/entidades/","Juego");
def("amicitia/modelo/entidades/","Grupo");
def("amicitia/modelo/entidades/","Persona");
def("amicitia/modelo/entidades/","Pareja");
def("amicitia/modelo/ejecucion/","Cupido");
def("amicitia/modelo/ejecucion/","Verificador");
def("amicitia/modelo/ejecucion/reglas/","ReglaBidireccional");
def("amicitia/modelo/ejecucion/reglas/","ReglaFamilia");
def("amicitia/modelo/ejecucion/reglas/","ReglaJuegoAnterior");
def("amicitia/modelo/ejecucion/reglas/","ReglaMismoSexo");
def("amicitia/modelo/ejecucion/reglas/","ReglaParejaImposible");
def("amicitia/pruebas/modelo/mocks/","VerificadorSimpleMock");
def("amicitia/persistencia/daos/","ConexionBD");

/**
 * Prueba el funcionamiento de Cupido y su capacidad de emparejar.
 * 
 * @author Willy A. Kuster
 */
class PruebaCupido extends PHPUnit_Framework_TestCase {
	
	private $jugador1;
	private $jugador2;
	private $jugador3;
	private $jugador4;
	private $juego;
	private $grupo;
	
	protected function setUp() {
		
		$this->jugador1 = new Persona();
		$this->jugador1->setId(10);
		$this->jugador1->setAlias("willykc");
		$this->jugador1->setNombre("Willy");
		$this->jugador1->setPassword("332caee2c3b1786392e8cf5f046f115edb206078");
		$this->jugador1->setApellido("Kuster");
		$this->jugador1->setEmail("willykc@gmail.com");
		$this->jugador1->setSexo("m");
		
		$this->jugador2 = new Persona();
		$this->jugador2->setId(7);
		$this->jugador2->setAlias("rigo");
		$this->jugador2->setPassword("461b992e3aaa155a76b273abaed0f616cd41ba1c");
		$this->jugador2->setNombre("Rigoberto");
		$this->jugador2->setApellido("Jorges");
		$this->jugador2->setEmail("rigzar@hotmail.com");
		$this->jugador2->setSexo("m");
		
		$this->jugador3 = new Persona();
		$this->jugador3->setId(6);
		$this->jugador3->setAlias("manzanita");
		$this->jugador3->setPassword("a8690d965bbb5f5818a13a8535afcdb3bc18da7c");
		$this->jugador3->setNombre("Xenia");
		$this->jugador3->setApellido("Marcinko");
		$this->jugador3->setEmail("manzanita_11@hotmail.com");
		$this->jugador3->setSexo("f");
		
		$this->jugador4 = new Persona();
		$this->jugador4->setId(9);
		$this->jugador4->setAlias("darm");
		$this->jugador4->setPassword("18807ca8a5865cb16eaf630cf4bf80251391bde2");
		$this->jugador4->setNombre("Daniel");
		$this->jugador4->setApellido("Rodriguez");
		$this->jugador4->setEmail("darmander@gmail.com");
		$this->jugador4->setSexo("m");
		
//		$jugador5 = new Persona();
//		$jugador5->setId(2);
//		$jugador5->setAlias("poko");
//		$jugador5->setPassword("poko");
//		$jugador5->setNombre("poko");
//		$jugador5->setApellido("poko");
//		$jugador5->setEmail("poko@gmail.com");
//		$jugador5->setSexo("m");
//		
//		$jugador6 = new Persona();
//		$jugador6->setId(3);
//		$jugador6->setAlias("piko");
//		$jugador6->setPassword("piko");
//		$jugador6->setNombre("piko");
//		$jugador6->setApellido("piko");
//		$jugador6->setEmail("piko@gmail.com");
//		$jugador6->setSexo("f");
		
		$jugadores = array();
		$jugadores[$this->jugador1->getId()] = $this->jugador1;
		$jugadores[$this->jugador2->getId()] = $this->jugador2;
		$jugadores[$this->jugador3->getId()] = $this->jugador3;
		$jugadores[$this->jugador4->getId()] = $this->jugador4;
//		$jugadores[$jugador5->getId()] = $jugador5;
//		$jugadores[$jugador6->getId()] = $jugador6;
		
		$this->juego = new Juego();
		$this->juego->setId(4);
		$this->juego->setOcasion("Navidades 2009");
		$this->juego->setFecha("2009-09-07 01:55:27");
		$this->juego->setReglas(null);
		$this->juego->setEstatus(Estatus::ACTIVO);
		$this->juego->setEsVisible(true);
		
		$this->grupo = new Grupo();
		$this->grupo->setId(1);
		$this->grupo->setNombre("Cubix");
		$this->grupo->setPassword("9d658601daa1ec698009c58d765de05d353b41eb");
		$this->grupo->setEsVisible(true);
		
		$this->juego->setGrupo($this->grupo);
		$this->juego->setJugadores($jugadores);
		$this->juego->setRegalantes(array());
		$this->juego->setRegalados(array());
		
	}
	
	/**
	 * Prueba la capacidad de Cupido de emparejar consistentemente.
	 */
	public function testEmparejarSimple() {
		
		$cupido = new Cupido(new VerificadorSimpleMock(true), $this->juego);
		
		$this->assertEquals(0,count($this->juego->getRegalantes()));
		$this->assertEquals(0,count($this->juego->getRegalados()));
		
		$pareja1 = $cupido->emparejar($this->jugador1);
		$this->assertContains($this->jugador1,$this->juego->getRegalantes());
		$this->assertEquals(1,count($this->juego->getRegalados()));
		
		$pareja2 = $cupido->emparejar($this->jugador2);
		$this->assertContains($this->jugador2,$this->juego->getRegalantes());
		$this->assertEquals(2,count($this->juego->getRegalados()));
		
		$pareja3 = $cupido->emparejar($this->jugador3);
		$this->assertContains($this->jugador3,$this->juego->getRegalantes());
		$this->assertEquals(3,count($this->juego->getRegalados()));
		
		$pareja4 = $cupido->emparejar($this->jugador4);
		$this->assertContains($this->jugador4,$this->juego->getRegalantes());
		$this->assertEquals(4,count($this->juego->getRegalados()));
		
		$this->assertEquals($this->juego->getJugadores(),$this->juego->getRegalados());
		$this->assertEquals($this->juego->getJugadores(),$this->juego->getRegalantes());
		
		$this->assertEquals($this->jugador1,$pareja1->getDador());
		$this->assertNotEquals($this->jugador1,$pareja1->getReceptor());
		
		$this->assertEquals($this->jugador2,$pareja2->getDador());
		$this->assertNotEquals($this->jugador2,$pareja2->getReceptor());
		
		$this->assertEquals($this->jugador3,$pareja3->getDador());
		$this->assertNotEquals($this->jugador3,$pareja3->getReceptor());
		
		$this->assertEquals($this->jugador4,$pareja4->getDador());
		$this->assertNotEquals($this->jugador4,$pareja4->getReceptor());
		
	}
	
	/**
	 * Prueba el cálculo del índice de convergencia de un juego.
	 */
	public function testConvergencia() {
		
		$cupido = new Cupido(new VerificadorSimpleMock(true), $this->juego);
		
		$estadisticas = $cupido->estadisticas();
		
		$this->assertGreaterThan(0,$estadisticas["convergencia"]);
		$this->assertGreaterThan(0,$estadisticas["permutaciones"]);
		$this->assertLessThanOrEqual(1,$estadisticas["convergencia"]);
		
	}
	
	/**
	 * Prueba el caso en que un juego no converge.
	 */
	public function testNoConvergencia() {
		
		$cupido = new Cupido(new VerificadorSimpleMock(false), $this->juego);
		
		$estadisticas = $cupido->estadisticas();
		
		$this->assertEquals(0,$estadisticas["convergencia"]);
		$this->assertEquals(0,$estadisticas["permutaciones"]);
		
	}
	
	/**
	 * Prueba el comportamiento de un juego con reglas.
	 */
	public function testJuegoConReglas() {
		
		ConexionBD::getConexionBD()->conectar();
		
		$reglaBidireccional = new ReglaBidireccional();
		$reglaJuegoAnterior = new ReglaJuegoAnterior();
		$reglaParejaImposible = new ReglaParejaImposible();
		
		$parejaImposible = new Pareja();
		$parejaImposible->setDador($this->jugador1);
		$parejaImposible->setReceptor($this->jugador2);
		$reglaParejaImposible->setParejaImposible($parejaImposible);
		$reglaParejaImposible->setBidireccional(true);
		
		$reglas[0] = $reglaBidireccional;
		$reglas[1] = $reglaJuegoAnterior;
		$reglas[2] = $reglaParejaImposible;
		
		$this->juego->setReglas($reglas);
		
		$cupido = new Cupido(new Verificador(), $this->juego);
		
		$estadisticas = $cupido->estadisticas();
	
//		echo "convergencia: ".$estadisticas["convergencia"];
//		echo "\npermutaciones: ".$estadisticas["permutaciones"];
	
		$pareja1 = $cupido->emparejar($this->jugador1);
	
		$pareja2 = $cupido->emparejar($this->jugador2);
		
		$pareja3 = $cupido->emparejar($this->jugador3);
		
		$pareja4 = $cupido->emparejar($this->jugador4);
		
		$this->assertGreaterThan(0,$estadisticas["convergencia"]);
		$this->assertGreaterThan(0,$estadisticas["permutaciones"]);
		$this->assertLessThanOrEqual(1,$estadisticas["convergencia"]);
		
		ConexionBD::getConexionBD()->deshacer();
		ConexionBD::getConexionBD()->desconectar();
		
	}
	
	protected function tearDown() {
		;
	}
	
}
?>